/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License"),
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @addtogroup TeeTrusted
 * @{
 *
 * @brief TEE（Trusted Excution Environment）可信执行环境API。
 *
 * 提供安全能力API，例如可信存储、加解密及可信时间等，用于可信应用程序开发。
 *
 * @since 20
 */

/**
 * @file tee_tui_gp_api.h
 *
 * @brief 提供TUI（可信用户界面）相关操作的API。
 *
 * @library NA
 * @kit TEEKit
 * @include <TEEKit/tee_tui_gp_api.h>
 * @syscap SystemCapability.Tee.TeeClient
 * @since 20
 */

#ifndef TASK_TUI_GP_API_H
#define TASK_TUI_GP_API_H

#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <tee_defines.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief 定义TEE TUI按钮类型的常量。
 *
 * @since 20
 */
#define TEE_TUI_NUMBER_BUTTON_TYPES 0x00000006

/**
 * @brief 定义TEE存储的私有区域标识符。
 *
 * @since 20
 */
#define TEE_STORAGE_PRIVATE         0x00000001

/**
 * @brief 定义默认的最大字段数。
 *
 * @since 20
 */
#define DEFAULT_MAX_ENTRY_FIELDS    3

/**
 * @brief 定义退出操作的标识符。
 *
 * @since 20
 */
#define TUI_EXIT                    8

/**
 * @brief 枚举在输入字段内显示字符时支持的模式。
 *
 * @since 20
 */
typedef enum {
    /** 永不显示，显示为 '*'。 */
    TEE_TUI_HIDDEN_MODE = 0,
    /** 始终可见。 */
    TEE_TUI_CLEAR_MODE,
    /** 显示后隐藏。 */
    TEE_TUI_TEMPORARY_CLEAR_MODE
} TEE_TUIEntryFieldMode;

/**
 * @brief 枚举TUI输入字段支持的输入类型。
 *
 * @since 20
 */
typedef enum {
    /** 字段仅接受数字输入。 */
    TEE_TUI_NUMERICAL = 0,
    /** 字段接受字符和数字输入。 */
    TEE_TUI_ALPHANUMERICAL,
} TEE_TUIEntryFieldType;

/**
 * @brief 枚举TUI屏幕的方向。
 * @attention 当前TEE_TUI_LANDSCAPE不支持。
 *
 * @since 20
 */
typedef enum {
    /** 以纵向显示，即竖屏。 */
    TEE_TUI_PORTRAIT = 0,
    /** 以横向显示，即横屏。 */
    TEE_TUI_LANDSCAPE,
} TEE_TUIScreenOrientation;

/**
 * @brief 枚举按钮的类型。
 *
 * @since 20
 */
typedef enum {
    /** 用于删除前一个输入的数字。 */
    TEE_TUI_CORRECTION = 0,
    /** 退出当前界面。 */
    TEE_TUI_OK,
    /** 取消操作并退出界面。 */
    TEE_TUI_CANCEL,
    /** 用于触发PIN验证并退出界面。 */
    TEE_TUI_VALIDATE,
    /** 退出当前界面并请求TA显示上一个界面。 */
    TEE_TUI_PREVIOUS,
    /** 退出当前界面并请求TA显示下一个界面。 */
    TEE_TUI_NEXT,
} TEE_TUIButtonType;

/**
 * @brief 枚举使用的图片来源。
 *
 * @since 20
 */
typedef enum {
    /** 输入中未提供图片。 */
    TEE_TUI_NO_SOURCE = 0,
    /** 图片通过内存指针提供。 */
    TEE_TUI_REF_SOURCE,
    /** 图片通过受信存储中的对象提供。 */
    TEE_TUI_OBJECT_SOURCE,
    /** 图片通过文件提供。 */
    TEE_TUI_FILE_SOURCE = 0x8001
} TEE_TUIImageSource;

/**
 * @brief 表示PNG格式的图像。
 *
 * @since 20
 */
typedef struct {
    /** 表示图像的来源。 */
    TEE_TUIImageSource source;
    /**
     * @brief 包含图像数据及其长度。
     *
     * @since 20
     */
    struct {
        /** 指向图像数据的指针。 */
        void *image;
        /** 图像数据的长度。 */
        size_t imageLength;
    } ref;
    /**
     * @brief 表示图像的对象存储信息。
     *
     * @since 20
     */
    struct {
        /** 图像存储所在的存储ID。 */
        uint32_t storageID;
        /** 指向图像存储的对象ID的指针。 */
        void *objectID;
        /** 对象ID的长度。 */
        size_t objectIDLen;
    } object;
    /** 图像的宽度（像素数）。 */
    uint32_t width;
    /** 图像的高度（像素数）。 */
    uint32_t height;
} TEE_TUIImage;

/**
 * @brief 枚举GP颜色索引。
 *
 * @since 20
 */
enum gp_color_idx {
    /** 红色索引。 */
    RED_IDX       = 0,
    /** 绿色索引。 */
    GREEN_IDX     = 1,
    /** 蓝色索引。 */
    BLUE_IDX      = 2,
    /** RGB颜色索引。 */
    RGB_COLOR_IDX = 3,
};

/**
 * @brief 表示用于TA品牌标识/信息的标签，通常显示在屏幕顶部。
 *
 * @since 20
 */
typedef struct {
    /** 显示在标签区域的字符串，可以为NULL。 */
    char *text;
    /** 文本信息左上角的X坐标。 */
    uint32_t textXOffset;
    /** 文本信息左上角的Y坐标。 */
    uint32_t textYOffset;
    /** 显示文本信息所使用的RGB颜色。 */
    uint8_t textColor[RGB_COLOR_IDX];
    /** 显示在标签区域的图像内容。 */
    TEE_TUIImage image;
    /** 图像左上角的X坐标。 */
    uint32_t imageXOffset;
    /** 图像左上角的Y坐标。 */
    uint32_t imageYOffset;
} TEE_TUIScreenLabel;

/**
 * @brief 表示按钮上显示的内容。
 *
 * @since 20
 */
typedef struct {
    /** 与按钮关联的字符串，可以为NULL。 */
    char *text;
    /** 与按钮关联的图片。 */
    TEE_TUIImage image;
} TEE_TUIButton;

/**
 * @brief 表示TUI屏幕的配置。
 *
 * @since 20
 */
typedef struct {
    /** 请求的屏幕方向。 */
    TEE_TUIScreenOrientation screenOrientation;
    /** 屏幕的标签。 */
    TEE_TUIScreenLabel label;
    /** 自定义的按钮，与默认按钮相比。 */
    TEE_TUIButton *buttons[TEE_TUI_NUMBER_BUTTON_TYPES];
    /** 指定要显示哪些按钮。 */
    bool requestedButtons[TEE_TUI_NUMBER_BUTTON_TYPES];
} TEE_TUIScreenConfiguration;

/**
 * @brief 表示TUI屏幕按钮的相关信息。
 * @attention buttonTextCustom和buttonImageCustom不能同时设置为true。
 *
 * @since 20
 */
typedef struct {
    /** 按钮文本的默认标签值。如果值为NULL，则表示该参数不可用。 */
    const char *buttonText;
    /** 按钮的像素宽度。
     * 如果按钮上的文本或图片不可自定义，则值为0。
     */
    uint32_t buttonWidth;
    /** 按钮的像素高度。
     * 如果按钮上的文本或图片不可自定义，则值为0。
     */
    uint32_t buttonHeight;
    /** 如果按钮上的文本不可自定义，则值为true。 */
    bool buttonTextCustom;
    /** 如果按钮上的图片不可自定义，则值为true。 */
    bool buttonImageCustom;
} TEE_TUIScreenButtonInfo;

/**
 * @brief 表示TUI上显示的信息。
 *
 * @since 20
 */
typedef struct {
    /** 可用的灰度位深。 */
    uint32_t grayscaleBitsDepth;
    /** 可用的红色深度级别。 */
    uint32_t redBitsDepth;
    /** 可用的绿色深度级别。 */
    uint32_t greenBitsDepth;
    /** 可用的蓝色深度级别。 */
    uint32_t blueBitsDepth;
    /** 表示水平方向上每英寸的像素数。 */
    uint32_t widthInch;
    /** 表示垂直方向上每英寸的像素数。 */
    uint32_t heightInch;
    /** 表示TUI上可以显示的最大条目数。 */
    uint32_t maxEntryFields;
    /** 表示输入区域标签的像素宽度。 */
    uint32_t entryFieldLabelWidth;
    /** 表示输入区域标签的像素高度。 */
    uint32_t entryFieldLabelHeight;
    /** 表示输入区域最大可输入字符数。 */
    uint32_t maxEntryFieldLength;
    /** 默认标签画布的RGB值。 */
    uint8_t labelColor[RGB_COLOR_IDX];
    /** 表示标签画布的像素宽度。 */
    uint32_t labelWidth;
    /** 表示标签画布的像素高度。 */
    uint32_t labelHeight;
    /** 表示界面上按钮的信息。 */
    TEE_TUIScreenButtonInfo buttonInfo[TEE_TUI_NUMBER_BUTTON_TYPES];
} TEE_TUIScreenInfo;

/**
 * @brief 表示需要用户输入的输入字段中的信息。
 *
 * @since 20
 */
typedef struct {
    /** 输入字段的标签。 */
    char *label;
    /** 用于显示字符的模式。 */
    TEE_TUIEntryFieldMode mode;
    /** 输入字段中可以输入的字符类型。 */
    TEE_TUIEntryFieldType type;
    /** 最小输入字符数。 */
    uint32_t minExpectedLength;
    /** 最大输入字符数。 */
    uint32_t maxExpectedLength;
    /** 包含用户输入的内容。 */
    char *buffer;
    /** 缓冲区的长度。 */
    size_t bufferLength;
} TEE_TUIEntryField;

/**
 * @brief 初始化TUI资源。
 *
 * @return TEE_SUCCESS：操作成功。\n
 *         TEE_ERROR_BAD_PARAMETERS：输入参数不正确。\n
 *         TEE_ERROR_NOT_SUPPORTED ：设备不支持 TUI。\n
 *         TEE_ERROR_BUSY ：TUI资源无法分配。\n
 *         TEE_ERROR_OUT_OF_MEMORY ：系统资源不足。
 * @since 20
 */
TEE_Result TEE_TUIInitSession(void);


/**
 * @brief 释放之前获得的TUI资源。
 *
 * @return TEE_SUCCESS：操作成功。\n
 *         TEE_ERROR_BAD_STATE ：当前TA不在通过成功调用 {@code TEE_TUIInitSession} 初始启动的TUI会话中。\n
 *         TEE_ERROR_BUSY ：TUI资源当前正在使用中。
 * @since 20
 */
TEE_Result TEE_TUICloseSession(void);

/**
 * @brief 允许TA检查给定的文本是否可以由当前实现渲染，并获取渲染该文本所需的大小和宽度信息。
 *
 * @param text 指定要检查的字符串。
 * @param width 指定渲染文本所需的宽度（以像素为单位）。
 * @param height 指定渲染文本所需的高度（以像素为单位）。
 * @param last_index 指定已检查的最后一个字符索引。
 *
 * @return TEE_SUCCESS：操作成功。\n
 *         TEE_ERROR_NOT_SUPPORTED ：文本字符串中的至少一个字符无法渲染。
 * @since 20
 */
TEE_Result TEE_TUICheckTextFormat(const char *text, uint32_t *width, uint32_t *height, uint32_t *last_index);

/**
 * @brief 根据屏幕方向和所需输入字段的数量，检索有关屏幕的信息。
 *
 * @param screenOrientation 定义请求屏幕信息的方向。
 * @param nbEntryFields 指定请求的输入字段的数量。
 * @param screenInfo 指定给定方向下请求的屏幕信息。
 *
 * @return TEE_SUCCESS：操作成功。\n
 *         TEE_ERROR_NOT_SUPPORTED ：不支持所请求的输入字段数量。
 * @since 20
 */
TEE_Result TEE_TUIGetScreenInfo(TEE_TUIScreenOrientation screenOrientation,
                                uint32_t nbEntryFields,
                                TEE_TUIScreenInfo *screenInfo);

/**
 * @brief 显示TUI屏幕。
 *
 * @param screenConfiguration 指定显示界面上的标签和可选按钮的配置。
 * @param closeTUISession 如果值为true，则在退出函数时自动关闭TUI会话。
 * @param entryFields 指定输入字段的信息。
 * @param entryFieldCount 指定输入字段的数量。
 * @param selectedButton 指示用户选择的按钮，用于退出TUI屏幕。
 *
 * @return TEE_SUCCESS：操作成功。\n
 *         TEE_ERROR_OUT_OF_MEMORY ：系统资源不足。\n
 *         TEE_ERROR_ITEM_NOT_FOUND ：TA提供的至少一张图片引用了一个不存在的存储区的storageID，
 * 或者无法在存储区中找到相应的对象标识符。\n
 *         TEE_ERROR_ACCESS_CONFLICT ：TA提供的至少一张图片引用了受信存储中的数据对象，
 * 且在打开该对象时检测到访问权限冲突。\n
 *         TEE_ERROR_BAD_FORMAT ：至少一张输入图片不符合PNG格式。\n
 *         TEE_ERROR_BAD_STATE ：当前TA不在通过成功调用TEE_TUIInitSession初始化启动的TUI会话中。\n
 *         TEE_ERROR_BUSY ：TUI资源当前正在使用，即TUI屏幕正在显示。\n
 *         TEE_ERROR_CANCEL ：在当前显示TUI屏幕时操作已被取消。\n
 *         TEE_ERROR_EXTERNAL_CANCEL：在当前显示TUI屏幕时，由于REE中发生的外部事件导致操作被取消。
 * @since 20
 */
TEE_Result TEE_TUIDisplayScreen(TEE_TUIScreenConfiguration *screenConfiguration,
                                bool closeTUISession,
                                TEE_TUIEntryField *entryFields,
                                uint32_t entryFieldCount,
                                TEE_TUIButtonType *selectedButton);

/**
 * @brief 指纹识别端口。
 *
 * @return TEE_SUCCESS：操作成功。\n
 *         TEE_ERROR_NOT_SUPPORTED：表示设备不支持TUI。
 * @since 20
 */
TEE_Result TEE_TUINotify_fp(void);

/**
 * @brief 设置中文字符编码。系统默认支持 UTF-8。
 *
 * @param type 指定编码类型。值1表示GBK。其他值不支持。
 *
 * @return TEE_SUCCESS：操作成功。\n
 *         TEE_ERROR_NOT_SUPPORTED：设备不支持此功能。\n
 *         TEE_ERROR_BAD_PARAMETERS：输入参数不正确。
 * @since 20
 */
TEE_Result TEE_TUISetInfo(int32_t type);

/**
 * @brief 向TUI发送消息。
 *
 * @param type 指定发送给TUI的消息。只支持TUI_EXIT。
 *
 * @return TEE_SUCCESS：操作成功。\n
 *         TEE_ERROR_BAD_PARAMETERS：输入参数不正确。
 * @since 20
 */
TEE_Result TEE_TUISendEvent(int32_t type);

/**
 * @brief 设置TUI背景图片。
 *
 * @param label 配置背景图片信息的标签变量。
 * 图片必须是PNG格式的数组形式。
 * @param len 指定标签的大小。
 *
 * @return TEE_SUCCESS：操作成功。\n
 *         TEE_ERROR_GENERIC：输入参数不正确。\n
 *         TEE_ERROR_ACCESS_DENIED}：权限验证失败。
 * @since 20
 */
TEE_Result TEE_TUISetLabel(TEE_TUIScreenLabel *label, uint32_t len);
#ifdef __cplusplus
}
#endif

#endif
/** @} */